use axum::{
    Extension, Router, extract::{Path, Request, State}, http::StatusCode, middleware::{self, Next}, response::{ IntoResponse, Redirect, Response}, routing::get
};

use axum::extract::ConnectInfo;
use axum_casbin::CasbinVals;

use crate::{rbac::{enforcer}, users::AuthSession};
use crate::download;
use crate::web::admin;
use crate::web::ai;

use crate::web::log;
use crate::logdb::write_log_async;
use crate::elfinder::elfinder_handler;
use crate::directories::{list_directories, list_subdirectories};
use crate::web::casbinauthz;
use crate::web::showlove;
use casbin::CoreApi;

use tower_http::services::ServeDir;

use http::{header::{CONTENT_TYPE, HeaderValue}};


pub async fn casbin_middleware(
    Extension(casbin_vals): Extension<CasbinVals>,
    req: Request,
    next: Next,
) -> impl IntoResponse {
    let sub = &casbin_vals.subject;
    let obj = req.uri().path();
    let act = req.method().as_str();

    // 关键修正：先获取读锁守卫，再通过守卫调用方法
    let enforcer = enforcer();
    let guard = enforcer.read().await; // 读锁守卫

    // 权限校验
    let allowed = guard.enforce((sub, obj, act)).unwrap_or(false);
    println!("[RBAC] 校验结果: {}", allowed);

    if allowed {
        next.run(req).await
    } else {
        (StatusCode::FORBIDDEN, "权限不足").into_response()
    }
}

pub async fn router() -> Router<()> {

    Router::new().route("/", get(self::get::protected))
                .route("/download/{*path}", axum::routing::get(download::download_file))
                .route("/upload", axum::routing::post(download::handle_upload))
                .route("/upload-chunk", axum::routing::post(download::upload_chunk))  // 新增的分片上传接口
                .route("/merge-chunks", axum::routing::post(download::merge_chunks))  // 新增的合并接口
                .route("/check-chunks", axum::routing::get(download::check_uploaded_chunks))
                .route("/lolcate", axum::routing::post(ai::post::handle_lolcate))
                .route("/pastebin", axum::routing::post(showlove::post::handle_pastebin))
                .route("/admin-settings", axum::routing::get(admin::get::admin_setting))
                .route("/user-management.html", axum::routing::get(admin::get::userman_setting))
                .route("/admin-user-management", axum::routing::get(admin::get::admin_userman_setting))
                .route("/system-settings", axum::routing::get(admin::get::sysset_setting))
                .route("/ai-search.html", axum::routing::get(ai::get::ai_search))
                .route("/showlovewall.html", axum::routing::get(showlove::get::show_love))
                .route("/changepassword", axum::routing::post(admin::post::change_password))
                .route("/saveqr", axum::routing::post(admin::post::saveqr))
                .route("/logs", axum::routing::get(log::get::log_lookup))
                .route("/auditor", axum::routing::get(log::get::auditor_log_lookup))
                .route("/auditor-settings.html", axum::routing::get(admin::get::auditor_setting))
                .route("/user-pwd-settings", axum::routing::get(admin::get::user_pwd_setting))
                .route("/deleteuser", axum::routing::delete(admin::delete::delete_user))
                .route("/adduser", axum::routing::post(admin::post::add_user))
                .route("/updateuser", axum::routing::post(admin::post::update_user))
                .route("/listusers", axum::routing::get(admin::get::list_users))
                .route("/elfinder", axum::routing::get(elfinder_handler))
                .route("/directories", axum::routing::get(list_directories))
                .route("/directories/{*path}", axum::routing::get(list_subdirectories))
                .route("/file-browser", axum::routing::get(admin::get::file_browser))
                .route("/saveroot", axum::routing::post(admin::post::saveroot))
                .route("/{*path}", axum::routing::get(download::list_files))
}

mod get {

    use super::*;

    pub async fn protected(auth_session: AuthSession, 
                             ConnectInfo(addr): ConnectInfo<std::net::SocketAddr>) -> impl IntoResponse {
        // 从请求中获取客户端IP

        println!("user login ip : {}", addr);
        match auth_session.user {
            Some(user) => {
                write_log_async( user.username.to_string(), "INFO".to_string(), addr.to_string(), "用户登陆".to_string(),  "登陆成功".to_string())
                        .await.expect("Failed to write log");
                if user.role == "configer" {                  

                    return download::tera_list_files( Path(crate::util::get_http_root_url())).await;
                } else if user.role == "auditor" {
                    return Redirect::to("/auditor").into_response();
                } else {
                    // admin                    
                    return Redirect::to("/admin-user-management").into_response();

                }
            },

            None => {
                println!("not found any session");
                return Redirect::to("/admin-user-management.html").into_response();
            }
        }
    }
}
